JavaScript 性能优化之节流和防抖

在js事件中, 一般像: 鼠标移动事件(onmousemove) ,页面滚动事件(onscroll) , 窗口缩放事件 (onresize) ,oninput 输入事件 事件触发频率非常快 ,轻轻一动就是触发几十次(如果每次触发的执行任务比较复杂,会严重影响性能)

优化方案(对一些没有必要的操作忽略):

节流:(在一段时间内只触发一次):当持续触发事件时,保证一定时间段内只调用一次事件处理函数

#box{
    position:absolute;
    left:50%;
    top:50%;
    width:100px;
    height:100px;
    background:red;
    border-radius:50%;
    display:none;
}
<div id="box"></div>
/*
            需求: 在移动时候 ,改变box的颜色, 停止就不需要改变颜色
        */
        var box = document.getElementById("box");
        var prevTime = null; //记录上一次改变颜色的时间

        window.onmousemove = function(e){
            //考虑到低版本的IE浏览器不支持e , 所以需要写兼容性
            var e = e || window.event ;

            var x = e.clientX - (box.offsetWidth/2);
            var y = e.clientY - (box.offsetHeight/2);
            //设置box的位置
            box.style.left = x + "px";
            box.style.top = y + "px";

            //使用js 获取css样式中的元素样式属性 = > getComputedStyle()
            if(getComputedStyle(box).display=="none"){
                    box.style.display = "block";
                }

            if(prevTime==null){//首次改色
                //在移动的时候 每隔一段时间内修改颜色
                console.log('正在修改颜色...');
                box.style.background = randomColor();
                prevTime = new Date().getTime();
             }else{//已经改过色
                if((new Date().getTime() - prevTime)>=200){
                    console.log('正在修改颜色2....');
                    box.style.background = randomColor();
                    //重新更新记录上一次改色的时间
                    prevTime = new Date().getTime();
                }
                console.log('正在修改颜色 ---- 对比....');
            }


         }
 //随机生成16进制颜色函数
         function randomColor(){
             var R = parseInt(Math.random()*256).toString(16); // 直接生成0-255之间的数字 ,转换成 16进制
             var G = parseInt(Math.random()*256).toString(16); // 直接生成0-255之间的数字 ,转换成 16进制
             var B = parseInt(Math.random()*256).toString(16); // 直接生成0-255之间的数字 ,转换成 16进制
             return "#"+R+G+B;
             }

防抖(函数):(自始至终只触发一次):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。

<div id="box"></div>
    /*
        需求: 在鼠标停止移动一段时间后(没有继续移动) ,自动隐藏box 
    **/
var box = document.getElementById("box");
        var timer = null;//延迟定时器
        window.onmousemove = function(e){
            //考虑到低版本的IE浏览器不支持e , 所以需要写兼容性
            var e = e || window.event ;

            var x = e.clientX - (box.offsetWidth/2);
            var y = e.clientY - (box.offsetHeight/2);
            //设置box的位置
            box.style.left = x + "px";
            box.style.top = y + "px";

            //获取行内样式
            /*if(box.style.display == "none"){
                box.style.display = "block";
            }*/

            //使用js 获取css样式中的元素样式属性 = > getComputedStyle()
            if(getComputedStyle(box).display=="none"){
                    box.style.display = "block";
                }

             console.log(x,y);

             //先清除之前的定时器
             if(timer!=null){
                //清除之前移动时设置的定时器
                clearTimeout(timer); 
                }
             //设置移动停止后 1s 自动隐藏
             timer = setTimeout(function(){
                 box.style.display = "none";
                 console.log('正在隐藏box');
                 },1000) 
         }